home *** CD-ROM | disk | FTP | other *** search
- _A COFF FILE LOADER FOR THE 34010_
- by Don Morgan
-
-
-
- [LISTING ONE]
-
- #include <fcntl.h>
- #include <sys\types.h>
- #include <sys\stat.h>
- #include <io.h>
- #include <conio.h>
- #include <string.h>
- #include <stdio.h>
- #include <malloc.h>
- #include <stdlib.h>
- #include "coff.h"
-
- struct main_header *m_hdr;
- struct opt_header *opt;
- struct sect_header section;
-
- void main(int argc, char **argv)
- {
- /**************** PART A *****************/
- int module, size, header, sect, j;
- unsigned long result;
- int bss_done = FALSE;
-
- unsigned char *receive_buffer;
- char tmp_buf[100];
- int data, i;
- if(argc != 2) {
- printf("\nno file given!");
- exit(-1);
- }
- module = open(argv[1], O_BINARY|O_RDONLY);
- if(module == -1){
- perror("\nopen failed!");
- exit(-1);
- }
- /**************************/
- /*read coff file into buffer*/
- size = filelength(module);
- file_buffer = (char *)malloc(size);
- if(file_buffer == NULL) {
- perror("\nnot enough memory!");
- exit (-1);
- }
- if((result = (long)read(module, file_buffer, size)) <= 0) {
- perror("\ncan't find file!\n");
- exit(-1);
- }
- close(module);
-
- /************ PART B *************/
- /*set up 34010 for loading*/
- /**************************/
- /*it is the users responsibility to set up the cntrl register*/
- /*please note that some of the register settings, such as the following*/
- /*are application dependent, this code is included only to show an*/
- /*example of low level setup for the 34010*/
- gsp_poke(cntrl, 0x4); /*sets cas before ras refresh*/
-
- /**************************/
- /*set up 34010 to restart correctly after loading program*/
- put_hstctl(hlt | cf | incr | incw | nmim | nmi_flg);
- data = get_hstctl();
- if(data != (hlt | cf | incr | incw | nmim | nmi_flg)) {
- printf("\nerror writing to hstctl!");
- exit(-1);
- }
-
- /************ PART C *************/
- /**************************/
- /*get contents of main header*/
- m_hdr = (struct main_header *) file_buffer;
- /*see if the file has a magic number*/
- if(m_hdr->magic_num !=FILE_MAGIC) {
- printf("\nnot a standard coff .out file!");
- exit(-1);
- }
- /*check to see whether there is an optional header*/
- if((m_hdr->opt_head != OPT_XST)){
- printf("file is not fully linked!");
- exit(-1);
- }
- /*get contents of optional header*/
- opt = (struct opt_header *) &file_buffer[OPT_OFST];
- /*see if the optional header has a magic number*/
- if(opt->magic_num !=OPT_MAGIC) {
- printf("\nnon standard file!");
- exit(-1);
- }
-
- /*************************************************/
- /*begin searching for and loading section headers find bss section first! */
- i = FIRST_HDR;
- for (j=0;((j<m_hdr->num_sects) && !bss_done) ;j++){
- strcpy(tmp_buf,&file_buffer[i]);
- if(!bss_done) {
- if(!(strcmp(tmp_buf, ".bss"))) {
- strcpy(section.name, tmp_buf);
- header = i;
- get_sect(header);
- bss_done = TRUE;
- }
- }
- i += SEC_OFST;
- }
- /*now load the other sections*/
- i = FIRST_HDR;
- for (j=0; j<m_hdr->num_sects;j++){
- strcpy(tmp_buf,&file_buffer[i]);
- if(strcmp(tmp_buf, ".bss")) {
- strcpy(section.name, tmp_buf);
- header = i;
- get_sect(header);
- }
- i += SEC_OFST;
- }
-
- /*release memory for file buffer*/
- free(file_buffer);
-
- /************ PART D *************/
- /*set up reset and interrupt vectors for the 34010 */
- /*usually, both the nmi and halt bits are set and then released */
- /*this code may differ depending upon the desires of the programmer */
- gsp_poke(intenb,0x0); /*no interrupts*/
- gsp_poke(nmi_vect, opt->entry_point);
- gsp_poke(nmi_vect+0x10, opt->entry_point >> 0x10);
- gsp_poke(reset,opt->entry_point);
- gsp_poke(reset+0x10,opt->entry_point >> 0x10);
- put_hstctl(hlt | incr | nmi_flg | incw | nmim);
- /*toggle the halt bit and go*/
- data = get_hstctl();
- data &= ~hlt;
- put_hstctl( data );
- }
-
- /*********** PART E *************/
- void get_sect(header)
- int header;
- {
- struct sect_header * ptr = (struct sect_header *)&file_buffer[header];
- load(ptr);
- }
- void load(ptr)
- struct sect_header *ptr;
- {
- /*here the flags are checked to determine whether the section is to be loaded or copied or ignored*/
- if((ptr->sect_size) && !(ptr->flags & STYP_DSECT) &&
- !(ptr->flags & STYP_NOLOAD)) {
- if(!(strcmp(ptr->name,".cinit"))
- && (ptr->flags & STYP_COPY))
- put_data(ptr);
- else
- if(((ptr->flags & STYP_TEXT)
- || (ptr->flags & STYP_DATA)
- || (!(strcmp(ptr->name,".cinit")
- && !(ptr->flags & STYP_COPY)))))
- load_block(ptr);
- }
- }
- void load_block(ptr)
- struct sect_header *ptr;
- {
- int data, temporary, hldr, limit;
- long i, j, file_pointer;
- file_pointer = ptr->raw_data;
- /*set the host interface up to point at the correct address*/
- #if MM
- *(gsp:>hstadrl) = ptr->virt_addr;
- *(gsp:>hstadrh) = ptr->virt_addr >> 0x10;
- #else
- outpw(io_hstadrl, (unsigned int)ptr->virt_addr);
- outpw(io_hstadrh, (unsigned int)ptr->virt_addr >> 0x10);
- #endif
- limit = (ptr->sect_size/0x10)-1;
- j=0;
- /*write each word to host interface*/
- for(i=0; i<=limit; i++){
- /*get the data from the file buffer and get it in the correct order before writing to the host interface*/
- data = (file_buffer[file_pointer+j++]&0xff);
- data += ((file_buffer[file_pointer+j++]&0xff)*0x100);
- #if MM
- *(gsp:>hstdata) = data;
- #else
- outpw(io_hstdata,data);
- #endif
- }
- /*compare data*/
- /*point at the correct address*/
- #if MM
- *(gsp:>hstadrl) = ptr->virt_addr;
- *(gsp:>hstadrh) = ptr->virt_addr >> 0x10;
- #else
- outpw(io_hstadrl, (unsigned int)ptr->virt_addr);
- outpw(io_hstadrh, (unsigned int)ptr->virt_addr>> 0x10);
- #endif
- limit = (ptr->sect_size/0x10)-1;
- j=0;
- for(i=0; i<=limit; i++){
- /*get the data*/
- data = (file_buffer[file_pointer+j++]&0xff);
- data += ((file_buffer[file_pointer+j++]&0xff)*0x100);
- #if MM
- hldr = *(gsp:>hstdata);
- #else
- hldr = inpw(io_hstdata);
- #endif
- if(hldr != data)
- printf("\ncompare error!");
- }
- }
- void put_data(ptr)
- struct sect_header *ptr;
- {
- int data, temporary, hldr, limit, num_words, num;
- long i, j, reloc_address, file_pointer;
- struct init_table * init;
- file_pointer = ptr->raw_data;
- do{
- init = (struct init_table *)&file_buffer[file_pointer];
- reloc_address = init->ptr_to_var;
- file_pointer += 6;
-
- /*point at relocation address*/
- #if MM
- *(gsp:>hstadrl) = reloc_address;
- *(gsp:>hstadrh) = reloc_address >> 0x10;
- #else
- outpw(io_hstadrl, (unsigned int)reloc_address);
- outpw(io_hstadrh, (unsigned int)reloc_address >> 0x10);
- #endif
-
- /*determine the amount of data to transfer and do it*/
- num_words = init->num_words;
- limit = --num_words;
- j=0;
- for(i=0; i<=limit; i++){
- data = (file_buffer[file_pointer+j++]&0xff);
- data += ((file_buffer[file_pointer+j++]&0xff)*0x100);
- #if MM
- *(gsp:>hstdata) = data;
- #else
- outpw(io_hstdata,data);
- #endif
- }
- /*now, do a data compare*/
- #if MM
- *(gsp:>hstadrl) = reloc_address;
- *(gsp:>hstadrh) = reloc_address >> 0x10;
- #else
- outpw(io_hstadrl, (unsigned int)reloc_address);
- outpw(io_hstadrh, (unsigned int)reloc_address >> 0x10);
- #endif
- num_words = init->num_words;
- limit = --num_words;
- j=0;
- for(i=0; i<=limit; i++){
- data = (file_buffer[file_pointer+j++]&0xff);
- data += ((file_buffer[file_pointer+j++]&0xff)*0x100);
- #if MM
- hldr = *(gsp:>hstdata);
- #else
- hldr = inpw(io_hstdata);
- #endif
- if(hldr != data)
- printf("\ndata compare error!");
- }
- file_pointer += j;
- }while(((int)file_buffer[file_pointer]) != 0x0);
- }
- /*set up the hstctl*/
- void put_hstctl(unsigned int value)
- {
- #if MM
- *(gsp:>hstctl) = value;
- #else
- outpw(io_hstctl,value);
- #endif
- }
- /*get current Hstclt setting*/
- unsigned int get_hstctl()
- {
- int value;
- #if MM
- value = *(gsp:>hstctl);
- #else
- value = inpw(io_hstctl);
- #endif
- return value;
- }
- /*set host interface to point at correct address*/
- void set_addr(unsigned long address)
- {
- #if MM
- *(gsp:>hstadrl) = address;
- *(gsp:>hstadrh) = address >> 0x10;
- #else
- outpw(io_hstadrl,(unsigned int)address);
- outpw(io_hstadrh,(unsigned int)address >> 0x10);
- #endif
- }
- void gsp_poke(unsigned long address, unsigned long value)
- {
- set_addr(address);
- #if MM
- *(gsp:>hstdata) = value;
- #else
- outpw(io_hstdata,(unsigned int)value);
- #endif
- }
- unsigned int gsp_peek(unsigned long address)
- {
- int value;
-
- set_addr(address);
- #if MM
- value = *(gsp:>hstdata);
- #else
- value = inpw(io_hstdata);
- #endif
- return value;
- }
-
-
-
-
- [LISTING TWO]
-
- #define FALSE 0
- #define TRUE 0x1
-
- #define MM TRUE
-
- /*physical addresses of memory mapped host interface*/
- #if MM
- _segment gsp = 0xc700;
- int _based(void) *hstctl = (int _based(void)*)0xe00;
- int _based(void) *hstdata = (int _based(void)*)0xf00;
- int _based(void) *hstadrh = (int _based(void)*)0xc00;
- int _based(void) *hstadrl = (int _based(void)*)0xd00;
- #else
- /*io mapped addresses of host interface*/
- io_hstctl = 0;
- io_hstdata = 0;
- io_hstadrh = 0;
- io_hstadrl = 0;
- #endif
-
- #define FILE_MAGIC 0x90
- #define OPT_MAGIC 0x108
- #define OPT_XST 0x1c
- #define OPT_OFST 0x14
- #define SEC_OFST 0x28
- #define FIRST_HDR 0x30
-
- #define cf 0x4000
- #define hlt 0x8000
- #define nmi_flg 0x100
- #define nmim 0x200
- #define incw 0x800
- #define incr 0x1000
-
- /*definitions*/
- /*file header flags*/
- #define F_RELFLG 0x1 /*relocation information stripped*/
- #define F_EXEC 0x2 /*file is relocateable*/
- #define F_LNNO 0x4 /*line numbers stripped*/
- #define F_LSYMS 0x10 /*local symbos stripped*/
- #define F_QR32WR 0x40 /*34010 byte ordering*/
-
- /*section header flags*/
- #define STYP_REG 0x0 /*regular section*/
- #define STYP_DSECT 0x1 /*dummy section*/
- #define STYP_NOLOAD 0x2 /*noload section*/
- #define STYP_GROUP 0x4 /*grouped section*/
- #define STYP_PAD 0x8 /*padding section*/
- #define STYP_COPY 0x10 /*copy section, important for .cinit*/
- #define STYP_TEXT 0x20 /*executable code*/
- #define STYP_DATA 0x40 /*initialized data*/
- #define STYP_BSS 0x80 /*uninitialized data*/
- #define STYP_ALIGN 0x100 /*aligned on cache boundary*/
-
- /*******************************************************/
- /*interrupt vector:*/
- #define reset 0xffffffe0
- #define nmi_vect 0xfffffee0
- /*******************************************************/
- /*i/o registers:*/
- #define refcnt 0xc00001f0
- #define dpyadr 0xc00001e0
- #define vcount 0xc00001d0
- #define hcount 0xc00001c0
- #define dpytap 0xc00001b0
- #define pmask 0xc0000160
- #define psize 0xc0000150
- #define convdp 0xc0000140
- #define convsp 0xc0000130
- #define intpend 0xc0000120
- #define intenb 0xc0000110
- #define hstctlh 0xc0000100
- #define hstctll 0xc00000f0
- #define hst_adrh 0xc00000d0
- #define hst_adrl 0xc00000e0
- #define hst_data 0xc00000c0
- #define cntrl 0xc00000b0
- #define dpyint 0xc00000a0
- #define dpystrt 0xc0000090
- #define dpyctl 0xc0000080
- #define vtotal 0xc0000070
- #define vsblnk 0xc0000060
- #define veblnk 0xc0000050
- #define vesync 0xc0000040
- #define htotal 0xc0000030
- #define hsblnk 0xc0000020
- #define heblnk 0xc0000010
- #define hesync 0xc0000000
- #define dac_wr 0xc7800
- #define ppl_rd 0xc7000
-
- /*header structures*/
- struct main_header {
- unsigned short int magic_num;
- unsigned short int num_sects;
- long int date_stamp;
- long int sym_table;
- long int entries;
- unsigned short int opt_head;
- unsigned short int flags;
- };
- struct opt_header {
- short int magic_num;
- short int version;
- unsigned long code_size;
- unsigned long init_size;
- unsigned long uninit_size;
- unsigned long entry_point;
- unsigned long start_text;
- unsigned long start_data;
- };
- struct sect_header {
- unsigned char name[8];
- unsigned long phys_addr;
- unsigned long virt_addr;
- unsigned long sect_size;
- unsigned long raw_data;
- unsigned long reloc;
- unsigned long num_entries;
- unsigned short int reloc_entries;
- unsigned short int line_entries;
- unsigned short int flags;
- unsigned char ch1;
- unsigned char page;
- };
- struct init_table {
- int num_words;
- long ptr_to_var;
- };
- /*video pointer*/
- char far *vid_mem;
- /*variable declarations*/
- int len, text_ptr, debug, coff_debug, fake;
- unsigned char *file_buffer;
- /*function prototypes*/
- long getint(int, int);
- void load(struct sect_header *);
- void load_block(struct sect_header *);
- void put_data(struct sect_header *);
- void put_hstctl(unsigned int);
- unsigned int get_hstctl(void);
- void set_addr(unsigned long int);
- void gsp_poke(unsigned long int, unsigned long int);
- unsigned int gsp_peek(unsigned long int);
- void get_sect(int);
-
-